navigator.getUserMedia = navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia ||
                         navigator.msGetUserMedia;

window.URL = window.URL || window.webkitURL;

var fx = !!window.mozRTCPeerConnection;

window.RTCPeerConnection = //window.RTCPeerConnection || 
                           window.webkitRTCPeerConnection ||
                           window.mozRTCPeerConnection;

if (typeof(window.RTCSessionDescription) !== 'function') {
  window.RTCSessionDescription = function(arg) {
    return arg;
  };
}

function wrapDescription(description) {
  if (typeof(window.RTCSessionDescription) === 'function') {
    return new RTCSessionDescription(description);
  } else {
    return description;
  }
}

function addStreamToVideo(stream, video) {
  if (typeof(video.mozSrcObject) !== 'undefined') {
    video.mozSrcObject = stream;
    video.play();
  } else {
    video.src = window.URL.createObjectURL(stream);
  }
}

function addIceCandidate(peerConnection, candidate) {
  if (typeof(window.RTCIceCandidate) === 'function') {
    peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
  } else {
    console.log('C', candidate);
    peerConnection.addIceCandidate(candidate);
  }
}

var stunServers = [
  "stun.l.google.com:19302",
  "stun1.l.google.com:19302",
  "stun2.l.google.com:19302",
  "stun3.l.google.com:19302",
  "stun4.l.google.com:19302",
  "stun01.sipphone.com",
  "stun.ekiga.net",
  "stun.fwdnet.net",
  "stun.ideasip.com",
  "stun.iptel.org",
  "stun.rixtelecom.se",
  "stun.schlund.de",
  "stunserver.org",
  "stun.softjoys.com",
  "stun.voiparound.com",
  "stun.voipbuster.com",
  "stun.voipstunt.com",
  "stun.voxgratia.org",
  "stun.xten.com"
];

if (navigator.getUserMedia) {
  navigator.getUserMedia({
    video: true,
    audio: !fx
  }, function(mediaStream) {

    console.log('stream', mediaStream);
    addStreamToVideo(mediaStream, document.getElementById('video'));

    if (fx) {
      navigator.getUserMedia({audio: true}, function(audio) {
        startSession(mediaStream, audio);
      }, function() {
        startSession(mediaStream, null);
      })
    } else {
      startSession(mediaStream);
    }

  }, function(err) {
    startSession(null, null);
    console.log('Failed to open stream', err);
  });
} else {
  startSession(null, null);
  console.log('getUserMedia not supported');
} 

localDescription = null;
remoteDescription = null;

function succ(e) {
  console.log('Success', e);
}

function err(e, e1) {
  console.log('Err', e, e1);
}

function startSession(stream, audio) {
  console.log('Start session', stream);

  var server = {
        /*iceServers: stunServers.map(function(server) {
          return {
            url: 'stun:' + server
          };
        })*/
        iceServers: [{
            url: 'turn:toto@184.73.229.17'
            ,            credential: 'password'
        }]
      }
    , socket =  io.connect(window.location.host, {
        port: 8080
      })
    , peerConnection
    , initiator = false
    , video = document.getElementById('video2')
    , status = document.getElementById('status');

  socket.on('startCall', function() {
    status.innerHTML = 'Calling...';

    startPeerConnection();

    initiator = true;

    peerConnection.createOffer(function(offer) {
      console.log('Create offer', offer);

      peerConnection.setLocalDescription(offer, function() {
        socket.emit('remoteDescription', offer);
      }, err);
    });

  });

  socket.on('iceCandidate', function(candidate) {
    
    console.log('Ice candidate from server', candidate.candidate);
    
    //candidate.candidate.replace('10.112.223.48', '100.22.221.71');

    if (peerConnection) {
      addIceCandidate(peerConnection, candidate);
    }
  });

  socket.on('remoteDescription', function(description) {
    var offer = description.type === 'offer';

    status.innerHTML = 'Session started, waiting video stream...';
    console.log('Remote description received', description, description.sdp);

    if (!peerConnection && offer) {
      startPeerConnection();
    }

    peerConnection.setRemoteDescription(wrapDescription(description), function() {
      if (offer) {
        peerConnection.createAnswer(function(answer) {
          console.log('Create answer', answer, answer.sdp);

          peerConnection.setLocalDescription(answer, function() {
            socket.emit('remoteDescription', answer);
          }, err);
        });
      } else {
        console.log('Call established');
      }
    }, err);
  });

  socket.on('endCall', function() {
    endPeerConnection();
  });

  socket.on('disconnect', function() {
    console.log('Socket disconnect');
    endPeerConnection();
  });

  function startPeerConnection() {
    peerConnection = new RTCPeerConnection(server);

    if (stream) {
      peerConnection.addStream(stream);
    }
    if (audio) {
     // peerConnection.addStream(audio);
    }

    peerConnection.onicecandidate = function(e) {
      console.log('Ice candidate event', e.canidate);

      if (e.candidate) {
      //e.candidate.candidate = e.candidate.candidate.replace('10.112.223.48', '100.22.221.71');
        socket.emit('iceCandidate', e.candidate);
      }
    };

    peerConnection.onaddstream = function(e) {
      status.innerHTML = 'Stream received, playing';

      console.log('Add stream event', e);

      //if (e.type === 'video') {
        addStreamToVideo(e.stream, video);
      //}
    };

    peerConnection.onstatechange = function(e) {
      if (peerConnection && peerConnection.readyState === 'closed') {
        endPeerConnection();
      }
    };
  }

  function endPeerConnection() {
    status.innerHTML = 'Call ended, waiting new call...';
    video.src = '';

    if (peerConnection) {
      peerConnection.close();
      peerConnection = null;
    }
  }
}

// function startPeerConnection(stream) {
//   var server = null;
//   // var pc1, pc2;

//   // create the 'sending' PeerConnection
//   pc1 = new RTCPeerConnection(server);

//   pc1.onconnecting = function(e) {
//     console.log('connection', e);
//   };

//   pc1.onopen = function(e) {
//     console.log('open', e);
//   };

//   pc1.onaddstream = function(e) {
//     console.log('addStream', e);
//   };

//   pc1.onremovestream = function(e) {
//     console.log('removeStream', e);
//   };

//   pc1.onicecandidate = function(e) {
//     if (e.candidate) {
//       pc2.addIceCandidate(new RTCIceCandidate(e.candidate));
//     }
//   };

//   pc2 = new RTCPeerConnection(server);

//   pc2.onicecandidate = function(e) {
//     if (e.candidate) {
//       pc1.addIceCandidate(new RTCIceCandidate(e.candidate));
//     }
//   };

//   pc2.onaddstream = function(e) {
//     console.log('Stream added',e);
//     var video = document.getElementById('video2');
//     video.src = window.URL.createObjectURL(e.stream);
//   };

//   pc1.addStream(stream);


//   pc1.createOffer(function(description1) {
//     pc1.setLocalDescription(description1);

//     pc2.setRemoteDescription(description1);

//     pc2.createAnswer(function(description2) {
//       pc2.setLocalDescription(description2);

//       pc1.setRemoteDescription(description2);
//     });
//     console.log('SDP', description1, description1.sdp);
//   });

// }